package myapps.ttclient.activity.ppt;

import java.util.ArrayList;
import myapps.ttclient.GlobalVariables;
import myapps.ttclient.Helper;
import myapps.ttclient.R;
import myapps.ttclient.adapter.PPTOpenFileArrayAdapter;
import myapps.ttclient.app.TTClientApplication;
import myapps.ttclient.baseclass_and_interface.TTConnectionStateChangedListener;
import myapps.ttclient.baseclass_and_interface.TTClientMessage;
import myapps.ttclient.baseclass_and_interface.TTClientMessageReceiver;
import myapps.ttclient.protocol.message.powerpoint.PPTOpenFileRequestMessage;
import myapps.ttclient.protocol.message.powerpoint.PPTOpenFileResponseMessage;
import myapps.ttclient.struct.FileInformationStruct;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class PPTOpenFileActivity extends Activity 
		implements TTClientMessageReceiver, TTConnectionStateChangedListener,
		OnItemClickListener, android.content.DialogInterface.OnClickListener
{
	private static final int REFRESH_MENU_ITEM_ID = 0;
	private static final int EXPLORE_ROOTS_MENU_ITEM_ID = 1;
	private static final int SORT_MENU_ITEM_ID = 2;
	private static final int FILTER_MENU_ITEM_ID = 3;
	private static final int BACK_MENU_ITEM_ID = 4;

	public static final int FILE_EXPLORER_ROOT = 1;
	public static final int FILE_EXPLORER_DIRECTORY = 2;
	public static final int FILE_EXPLORER_FILE = 3;

	private TTClientApplication application;
	private SharedPreferences preferences;

	private String directory;

	private ArrayList<FileInformationStruct> fileInfos;
	private ArrayAdapter<FileInformationStruct> adapter;

	private ListView listView;

	private TextView tvDirectory;
	
	private Boolean bFilter = false;
	private String currentDirectory = "";
	private FileInformationStruct[] currentFileInfos = null;
	
	private AlertDialog pptFileContextMenuDialog = null;
	private AlertDialog sortDialog = null;
	private AlertDialog filterDialog = null;

	private int currentPosition;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Helper.updateFullscreenStatus(this, true);

		//Helper.keepScreenOn(this);

		super.onCreate(savedInstanceState);

		this.application = (TTClientApplication) this.getApplication();

		this.preferences = this.application.getPreferences();

		this.setContentView(R.layout.openfile);

		this.listView = (ListView) this.findViewById(R.id.files);

		this.tvDirectory = (TextView) this.findViewById(R.id.directory);
		this.tvDirectory.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				AlertDialog.Builder builder = new AlertDialog.Builder(PPTOpenFileActivity.this);

				builder.setMessage(PPTOpenFileActivity.this.directory)
				.setCancelable(false)
				.setPositiveButton("Close", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {

					}
				});
				AlertDialog alert = builder.create();
				alert.show();
			}
		});

		this.fileInfos = new ArrayList<FileInformationStruct>();

		this.adapter = new PPTOpenFileArrayAdapter(this, R.layout.openfile_rowlayout, fileInfos);

		this.listView.setAdapter(this.adapter);

		this.listView.setOnItemClickListener(this);

		this.directory = this.preferences.getString("fileExplore_directory_ppt", "");

		this.initDialogs();
	}

	@Override
	protected void onResume() {
		super.onResume();

		this.application.registerMessageReceiver(this);
		this.application.registerConnectionStateChangedListener(this);

		this.directory = this.preferences.getString("fileExplore_directory_ppt", "");

		this.refresh();
	}

	@Override
	protected void onPause() {
		super.onPause();

		this.application.unregisterMessageReceiver(this);
		this.application.unregisterConnectionStateChangedListener(this);

		Editor editor = this.preferences.edit();
		editor.putString("fileExplore_directory_ppt", this.directory);
		editor.commit();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(Menu.NONE, REFRESH_MENU_ITEM_ID, Menu.NONE, "Refresh");
		menu.add(Menu.NONE, EXPLORE_ROOTS_MENU_ITEM_ID, Menu.NONE, "Root");
		menu.add(Menu.NONE, SORT_MENU_ITEM_ID, Menu.NONE, "Sort");
		menu.add(Menu.NONE, FILTER_MENU_ITEM_ID, Menu.NONE, "Filter");
		menu.add(Menu.NONE, BACK_MENU_ITEM_ID, Menu.NONE, "Back Screen");

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case REFRESH_MENU_ITEM_ID:
			this.application.showToast("Refresh");
			this.refreshConnection();
			break;
			
		case EXPLORE_ROOTS_MENU_ITEM_ID:
			this.application.showToast("Root");
			this.exploreRoots();
			break;
			
		case SORT_MENU_ITEM_ID:
			//this.application.showToast("Sort");
			this.sortDialog.show();
			break;
			
		case FILTER_MENU_ITEM_ID:
			//this.application.showToast("Filter");
			this.filterDialog.show();
			break;
			
		case BACK_MENU_ITEM_ID:
			this.finish();
			break;
			
		}

		return true;
	}

	private void upFolder() {
		String dir = this.directory;

		int idx_1 = dir.lastIndexOf("\\");

		if(idx_1 != -1) {
			// Exclude ""
			
			int idx_2 = dir.indexOf("\\");

			if((idx_1 == idx_2) && (idx_1 == (this.directory.length() - 1))) {
				this.directory = "";
			
			} else {
				//In the case "C:\\Windows\\APPs\\"	
				dir = dir.substring(0, dir.length()-1); // Bot di mot ky tu
				dir = dir.substring(0, dir.lastIndexOf("\\")) + "\\";
				this.directory = dir;
			}

			this.refresh();
		} else {
			this.application.showToast("Invalid Operation");
		}
	}

	public void receiveMessage(TTClientMessage message) {
		if (message instanceof PPTOpenFileResponseMessage) {
			PPTOpenFileResponseMessage rm = (PPTOpenFileResponseMessage) message;

			currentDirectory = rm.directory;
			currentFileInfos = rm.fileInfos;

			this.updateList();
			this.updateListView();
		}
	}
	
	private Boolean check_a_following_b(FileInformationStruct a, FileInformationStruct b) {
		if(a.type == b.type) {
			if(a.path != null && b.path != null) {
				if(a.path.compareToIgnoreCase(b.path) > 0) {
					return true;
				}
			}
		}
		
		return false;
	}
	
	private Boolean check_a_following_b_3(FileInformationStruct a, FileInformationStruct b) {
		if(a.type == b.type) {
			if(a.path != null && b.path != null) {
				if(a.path.compareToIgnoreCase(b.path) < 0) {
					return true;
				}
			}
		}
		
		return false;
	}
	
	private Boolean check_a_following_b_2(FileInformationStruct a, FileInformationStruct b) {
		if(a.type == FileInformationStruct.FILE && b.type != FileInformationStruct.FILE) {
			return true;
		}
		
		return false;
	}
	
	private void sort(Boolean bAscending) {
		ArrayList<FileInformationStruct> fileInfos = this.fileInfos;
		int s = fileInfos.size();
		
		if(bAscending) {
			for(int i = 0; i <= s - 2; i++) {
				for(int j = i + 1; j <= s - 1; j++) {
					if(check_a_following_b(fileInfos.get(i), fileInfos.get(j)) 
							|| check_a_following_b_2(fileInfos.get(i), fileInfos.get(j)))
					{	
						FileInformationStruct temp = fileInfos.get(i);
						fileInfos.set(i, fileInfos.get(j));
						fileInfos.set(j, temp);
					}
				}
			}
		} else {
			for(int i = 0; i <= s - 2; i++)	{
				for(int j = i + 1; j <= s - 1; j++)	{
					if( (check_a_following_b_3(fileInfos.get(i), fileInfos.get(j)))
							|| check_a_following_b_2(fileInfos.get(i), fileInfos.get(j)))
					{
						FileInformationStruct temp = fileInfos.get(i);
						fileInfos.set(i, fileInfos.get(j));
						fileInfos.set(j, temp);
					}
				}
			}
		}
	}

	
	private FileInformationStruct[] filterFileInfos(FileInformationStruct[] fileInfos) {
		if(fileInfos == null){
			return null;
		}

		if(bFilter == true) {
			ArrayList<FileInformationStruct> out = new ArrayList<FileInformationStruct>();

			int n = fileInfos.length;

			for (int i = 0; i < n; i++) {
				if(fileInfos[i].type != FileInformationStruct.FILE) {
					out.add(fileInfos[i]);

				} else {
					String s = Helper.getName(fileInfos[i].path);

					if(s.contains(".pptx") == true || s.contains(".ppt") == true){
						out.add(fileInfos[i]);

					}		
				}
			}

			int size = out.size();
			
			FileInformationStruct[] output = new FileInformationStruct[size];
			
			for (int i = 0; i < size; i++) {
				output[i] = out.get(i);
			}
			
			return output;

		} else {
			return fileInfos;

		}
	}

	public void updateList() {
		String directory = this.currentDirectory; 

		FileInformationStruct[] fileInfos = filterFileInfos(this.currentFileInfos);

		this.directory = directory;

		this.fileInfos.clear();

		if(fileInfos != null) {
			for (int i = 0; i < fileInfos.length; i++) {
				FileInformationStruct fileInfo = new FileInformationStruct();
				fileInfo.path = fileInfos[i].path;
				fileInfo.type = fileInfos[i].type;

				this.fileInfos.add(fileInfo);
			}
		}
	}
	
	private void updateListView() {
		this.runOnUiThread(new Runnable() {
			public void run() {
				String str = PPTOpenFileActivity.this.getShortPath(PPTOpenFileActivity.this.directory);
				if(str == "") {
					PPTOpenFileActivity.this.tvDirectory.setText("Root");
				
				} else {
					PPTOpenFileActivity.this.tvDirectory.setText(str);
				
				}

				PPTOpenFileActivity.this.adapter.notifyDataSetChanged();
				PPTOpenFileActivity.this.listView.setSelectionAfterHeaderView();
			}
		});		
	}

	private String getShortPath(String path) {
		int nTotal = path.length();

		if(nTotal > 100) {
			return path.substring(0,9) + "...." + path.substring(path.length() - 70, path.length());
		
		} else {
			return path;
		
		}
	}

	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		this.currentPosition = position;

		String path = this.fileInfos.get(position).path;
		int type = this.fileInfos.get(position).type;

		if(type == FileInformationStruct.FIXED) {
			this.application.sendMessage(
					new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
							PPTOpenFileActivity.FILE_EXPLORER_DIRECTORY	, path));
		
		} else if (type == FileInformationStruct.FOLDER) {
			//Directory
			this.application.sendMessage(
					new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
							PPTOpenFileActivity.FILE_EXPLORER_DIRECTORY	, path + "\\"));

		} else if(type == FileInformationStruct.FILE){
			//File

			//			this.application.sendMessage(
			//					new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
			//							PPTOpenFileActivity.FILE_EXPLORER_FILE	, path));

			String s = Helper.getName(fileInfos.get(position).path);

			if(s.contains(".pptx") == true || s.contains(".ppt") == true){
				pptFileContextMenuDialog.show();

			} else {
				this.application.showToast("File type not supported");
			}
		}
	}

	private void refresh() {
		if(this.directory == "") {
			this.application.sendMessage(
					new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
							PPTOpenFileActivity.FILE_EXPLORER_ROOT	, ""));
		} else {
			this.application.sendMessage(
					new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
							PPTOpenFileActivity.FILE_EXPLORER_DIRECTORY	, this.directory));
		}
	}

	private void exploreRoots() {
		this.application.sendMessage(
				new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
						PPTOpenFileActivity.FILE_EXPLORER_ROOT	, ""));
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode ==  KeyEvent.KEYCODE_BACK) {
			if("".equals(this.directory) != true) {
				this.upFolder();
			} else {
				this.finish();
			}

			return true;
		}

		return super.onKeyDown(keyCode, event);
	}

	public void onConnectionStateChanged() {
		this.refresh();
	}

	public void refreshConnection()	{
		this.application.unregisterMessageReceiver(this);
		this.application.registerMessageReceiver(this);
		this.refresh();
	}

	

	private void initDialogs() {
		AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
		builder1.setItems(R.array.open_file_context_menu_item_name, this);
		pptFileContextMenuDialog = builder1.create();

		AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
		builder2.setItems(R.array.open_file_sort, this);
		sortDialog = builder2.create();

		AlertDialog.Builder builder3 = new AlertDialog.Builder(this);
		builder3.setItems(R.array.ppt_open_file_filter, this);
		filterDialog = builder3.create();
	}


	@Override
	public void onClick(DialogInterface dialog, int which) {

		if(dialog == pptFileContextMenuDialog) {

			int position = this.currentPosition;
			String path = this.fileInfos.get(position).path;

			if(which == 0) { // Open
				//this.application.showToast("1");

				this.application.sendMessage(
						new PPTOpenFileRequestMessage(GlobalVariables.getTemporaryKey(), 
								PPTOpenFileActivity.FILE_EXPLORER_FILE	, path));

			} else if(which == 1) { // Details
				//this.application.showToast("2");
				
				Intent intent = new Intent(PPTOpenFileActivity.this, PPTFileDetailsActivity.class);
				intent.putExtra("FILE_PATH", path);
				
				PPTOpenFileActivity.this.startActivity(intent);
				
			} else if(which == 2) { // Cancel
				//this.application.showToast("3");

			} 
		}

		if(dialog == sortDialog) { 
			if(which == 0) { // Sort by name in ascending order
				//this.application.showToast("4");
				this.sort(true);
				this.updateListView();

			} else if(which == 1) { // Sort by name in descending order
				//this.application.showToast("5");
				this.sort(false);
				this.updateListView();
				
			} else if(which == 2) { // Cancel
				//this.application.showToast("6");

			} 
		}

		if(dialog == filterDialog) {
			if(which == 0) { // *.ppt | *.pptx 
				//this.application.showToast("7");
				this.bFilter = true;
				this.updateList();
				this.updateListView();

			} else if(which == 1) { // *.* All files
				//this.application.showToast("8");
				this.bFilter = false;
				this.updateList();
				this.updateListView();
				
			} else if(which == 2) { // Cancel 
				//this.application.showToast("9");

			} 
		}
	}
}
